package com.luoke.util.myjdbc;

import cn.hutool.core.util.StrUtil;
import com.luoke.util.myjdbc.util.DBUtil;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class QueryWrapper<T> {

    private StringBuffer sql = new StringBuffer();
    private List<String> params = new ArrayList<>();
    private List<Object> tables = new ArrayList();
    private Class<T> clazz;
//    private Integer pageNum;
//    private Integer pageSize;
//    private List<Integer> limit = new ArrayList<>();

    public QueryWrapper<T> where(SFunction<T> sf, String var) {
        String fieldName = DBUtil.getFieldName(sf);
        String where = SQLEnum.WHERE + StrUtil.SPACE + fieldName + SQLEnum.EQ_SIGN.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(where);
        params.add(var);
        return this;
    }

    public QueryWrapper<T> where(String fieldName, String var) {
        String where = SQLEnum.WHERE + StrUtil.SPACE + fieldName + SQLEnum.EQ_SIGN.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(where);
        params.add(var);
        return this;
    }

    public QueryWrapper<T> where(SFunction<T> sf, String var, SQLEnum sqlEnum) {
        String fieldName = DBUtil.getFieldName(sf);
        String where = SQLEnum.WHERE + StrUtil.SPACE + fieldName + sqlEnum.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(where);
        params.add(var);
        return this;
    }

    public QueryWrapper<T> and(SFunction<T> sf, String var) {
        String fieldName = DBUtil.getFieldName(sf);
        String and = SQLEnum.AND + StrUtil.SPACE + fieldName + SQLEnum.EQ_SIGN.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(and);
        params.add(var);
        return this;
    }

    public QueryWrapper<T> and(SFunction<T> sf, String var, SQLEnum sqlEnum) {
        String fieldName = DBUtil.getFieldName(sf);
        String and = SQLEnum.AND + StrUtil.SPACE + fieldName + sqlEnum.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(and);
        params.add(var);
        return this;
    }

    public QueryWrapper<T> or(SFunction<T> sf, String var) {
        String fieldName = DBUtil.getFieldName(sf);
        String or = SQLEnum.OR + StrUtil.SPACE + fieldName + SQLEnum.EQ_SIGN.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(or);
        params.add(var);
        return this;
    }

    public QueryWrapper<T> or(SFunction<T> sf, String var, SQLEnum sqlEnum) {
        String fieldName = DBUtil.getFieldName(sf);
        String or = SQLEnum.OR + StrUtil.SPACE + fieldName + sqlEnum.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        sql.append(or);
        params.add(var);
        return this;
    }

    @SuppressWarnings("unchecked")
    public QueryWrapper<T> select(SFunction<T>... sf) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < sf.length; i++) {
            String fieldName = DBUtil.getFieldName(sf[i]);
            list.add(fieldName);
        }
        String filedList = StrUtil.join(SQLEnum.COMMA_SIGN.getValue(), list);//"user,age"
        String select = SQLEnum.SELECT + StrUtil.SPACE + filedList + StrUtil.SPACE;
        sql.append(select);
        return this;
    }

    @SuppressWarnings("unchecked")
    public QueryWrapper<T> select(String... FieldName) {
        String select = null;
        if (SQLEnum.ASTERISK_SIGN.getValue().equals(FieldName[0])) {
            select = SQLEnum.SELECT + SQLEnum.ASTERISK_SIGN.getValue();
        } else {
            select = SQLEnum.SELECT + StrUtil.join(SQLEnum.COMMA_SIGN.getValue(), FieldName);
        }
        sql.append(select);
        return this;
    }

    public QueryWrapper<T> from(Class<T> clazz) {
        this.clazz = clazz;
        String simpleName = clazz.getSimpleName();
        String tableName = StrUtil.toUnderlineCase(simpleName);//转成下划线
        String from = SQLEnum.FROM + StrUtil.SPACE + tableName + StrUtil.SPACE;
        sql.append(from);
        return this;
    }

//    public QueryWrapper<T> from(String  tableName) {
//        String from = SQLEnum.FROM + StrUtil.SPACE + tableName + StrUtil.SPACE;
//        sql.append(from);
//        return this;
//    }

    public QueryWrapper<T> orderBy(SFunction<T> sf, SQLEnum sqlEnum) {
        String fieldName = DBUtil.getFieldName(sf);
        String orderBy = SQLEnum.ORDER_BY.getValue() + StrUtil.SPACE + fieldName + StrUtil.SPACE + sqlEnum.getValue() + StrUtil.SPACE;
        sql.append(orderBy);
        return this;
    }

    public QueryWrapper<T> orderBy(SFunction<T> sf1, SFunction<T> sf2, SQLEnum sqlEnum) {
        String fieldName1 = DBUtil.getFieldName(sf1);
        String fieldName2 = DBUtil.getFieldName(sf2);
        String orderBy = SQLEnum.ORDER_BY.getValue() + StrUtil.SPACE + fieldName1 + StrUtil.SPACE + sqlEnum.getValue() + StrUtil.SPACE+SQLEnum.COMMA_SIGN.getValue()+fieldName2 + StrUtil.SPACE + sqlEnum.getValue() + StrUtil.SPACE;
        sql.append(orderBy);
        return this;
    }

    public QueryWrapper<T> orderBy(String fieldName, SQLEnum sqlEnum) {
        String orderBy = SQLEnum.ORDER_BY.getValue() + StrUtil.SPACE + fieldName + StrUtil.SPACE + sqlEnum.getValue() + StrUtil.SPACE;
        sql.append(orderBy);
        return this;
    }

    public QueryWrapper<T> groupBy(SFunction<T> sf) {
        String fieldName = DBUtil.getFieldName(sf);
        String groupBy = SQLEnum.GROUP_BY.getValue() + StrUtil.SPACE + fieldName + StrUtil.SPACE;
        sql.append(groupBy);
        return this;
    }

    public QueryWrapper<T> leftJoin(Class<?> clazz) {
        String simpleName = clazz.getSimpleName();
        String tableName = StrUtil.toUnderlineCase(simpleName);//转成下划线
        String leftJoin = SQLEnum.LEFT_JOIN + StrUtil.SPACE + tableName + StrUtil.SPACE;
        sql.append(leftJoin);
        return this;
    }

    public QueryWrapper<T> leftJoin(String tableName) {
        String leftJoin = SQLEnum.LEFT_JOIN + StrUtil.SPACE + tableName;
        sql.append(leftJoin);
        return this;
    }

    public QueryWrapper<T> rightJoin(String tableName) {
        String rightJoin = SQLEnum.RIGHT_JOIN + StrUtil.SPACE + tableName;
        sql.append(rightJoin);
        return this;
    }

    public QueryWrapper<T> on(SFunction<T> sf1, String fieldName2) {
        String fieldName1 = DBUtil.getFieldName(sf1);
//        String on = SQLEnum.ON + StrUtil.SPACE + fieldName + SQLEnum.EQ_SIGN.getValue() + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
//        sql.append(on);
//        params.add(var);
        return this;
    }

    public QueryWrapper<T> like(SFunction<T> sf, String var) {
        String fieldName = DBUtil.getFieldName(sf);
        String like;
        String _var = SQLEnum.PER_SIGN.getValue() + var + SQLEnum.PER_SIGN.getValue();
        //判断有没有 WHERE语句
        if (sql.toString().contains(SQLEnum.WHERE.toString())) {
            like = SQLEnum.AND + StrUtil.SPACE + fieldName + StrUtil.SPACE + SQLEnum.LIKE.getValue() + StrUtil.SPACE + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        } else {
            like = SQLEnum.WHERE + StrUtil.SPACE + fieldName + StrUtil.SPACE + SQLEnum.LIKE.getValue() + StrUtil.SPACE + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        }
        sql.append(like);
        params.add(_var);
        return this;
    }

    public QueryWrapper<T> rightLike(SFunction<T> sf, String var) {
        String fieldName = DBUtil.getFieldName(sf);
        String like;
        String _var = var + SQLEnum.PER_SIGN.getValue();
        //判断有没有 WHERE语句
        if (sql.toString().contains(SQLEnum.WHERE.toString())) {
            like = SQLEnum.AND + StrUtil.SPACE + fieldName + StrUtil.SPACE + SQLEnum.LIKE.getValue() + StrUtil.SPACE + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        } else {
            like = SQLEnum.WHERE + StrUtil.SPACE + fieldName + StrUtil.SPACE + SQLEnum.LIKE.getValue() + StrUtil.SPACE + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        }
        sql.append(like);
        params.add(_var);
        return this;
    }

    public QueryWrapper<T> leftLike(SFunction<T> sf, String var) {
        String fieldName = DBUtil.getFieldName(sf);
        String like;
        String _var = SQLEnum.PER_SIGN.getValue() + var;
        //判断有没有 WHERE语句
        if (sql.toString().contains(SQLEnum.WHERE.toString())) {
            like = SQLEnum.AND + StrUtil.SPACE + fieldName + StrUtil.SPACE + SQLEnum.LIKE.getValue() + StrUtil.SPACE + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        } else {
            like = SQLEnum.WHERE + StrUtil.SPACE + fieldName + StrUtil.SPACE + SQLEnum.LIKE.getValue() + StrUtil.SPACE + SQLEnum.QUE_SIGN.getValue() + StrUtil.SPACE;
        }
        sql.append(like);
        params.add(_var);
        return this;
    }

    public QueryWrapper<T> limit(Integer pageNum, Integer pageSize) {
        String limit = SQLEnum.LIMIT.getValue() + StrUtil.SPACE + pageNum + SQLEnum.COMMA_SIGN.getValue() + pageSize;
        sql.append(limit);
        return this;
    }
}
